"""Cache Warmup Service - Preload property features at startup."""

import asyncio
import logging
from typing import TYPE_CHECKING, Any

from sqlalchemy.orm import Session

from .ai_extraction_service import AIExtractionService

if TYPE_CHECKING:
    from ..models.property import Property

logger = logging.getLogger(__name__)


class CacheWarmupService:
    """缓存预热服务 - 应用启动时批量加载房源特征."""

    def __init__(self, ai_service: AIExtractionService):
        """
        初始化缓存预热服务.

        Args:
            ai_service: AI提取服务实例
        """
        self.ai_service = ai_service
        self._warmup_stats = {
            "total": 0,
            "success": 0,
            "failed": 0,
            "cache_hits": 0,
        }

    async def warmup_property_cache(self, db: Session, batch_size: int = 50) -> dict[str, Any]:
        """
        预热房源特征缓存.

        Args:
            db: 数据库会话
            batch_size: 批次大小(默认50)

        Returns:
            dict: 预热统计信息
        """
        from ..models.property import Property

        logger.info("🔥 Starting property cache warmup...")

        # 获取所有可用房源
        properties = db.query(Property).filter(Property.is_deleted == False).all()  # noqa: E712

        self._warmup_stats["total"] = len(properties)
        logger.info(f"📊 Found {len(properties)} properties to warm up")

        if not properties:
            logger.warning("⚠️ No properties found to warm up cache")
            return self._warmup_stats

        # 分批处理避免内存溢出
        for i in range(0, len(properties), batch_size):
            batch = properties[i : i + batch_size]
            await self._warmup_batch(
                batch, i // batch_size + 1, (len(properties) + batch_size - 1) // batch_size
            )

        logger.info(f"✅ Cache warmup completed: {self._warmup_stats}")
        return self._warmup_stats

    async def _warmup_batch(
        self, properties: list["Property"], batch_num: int, total_batches: int
    ) -> None:
        """
        预热一批房源.

        Args:
            properties: 房源列表
            batch_num: 当前批次号
            total_batches: 总批次数
        """
        logger.info(
            f"🔄 Processing batch {batch_num}/{total_batches} ({len(properties)} properties)"
        )

        tasks = []
        for prop in properties:
            # 使用异步任务并发提取
            task = asyncio.create_task(self._warmup_single_property(prop))
            tasks.append(task)

        # 等待所有任务完成
        await asyncio.gather(*tasks, return_exceptions=True)

    async def _warmup_single_property(self, property: "Property") -> None:
        """
        预热单个房源特征.

        Args:
            property: 房源对象
        """
        try:
            # 检查缓存是否已存在
            cache_key = f"prop_feat_{property.id}_{hash(property.notes or '')}"
            if cache_key in self.ai_service._property_cache:
                self._warmup_stats["cache_hits"] += 1
                return

            # 在线程池中执行同步提取(避免阻塞)
            loop = asyncio.get_event_loop()
            await loop.run_in_executor(None, self.ai_service.extract_property_features, property)

            self._warmup_stats["success"] += 1
            logger.debug(f"✓ Cached property {property.id}: {property.community_name}")

        except Exception as e:
            self._warmup_stats["failed"] += 1
            logger.warning(f"✗ Failed to cache property {property.id}: {e}")

    def get_stats(self) -> dict[str, Any]:
        """
        获取预热统计信息.

        Returns:
            dict: 统计数据
        """
        return self._warmup_stats.copy()

    async def warmup_on_startup(self, db: Session) -> None:
        """
        应用启动时自动预热.

        Args:
            db: 数据库会话
        """
        try:
            stats = await self.warmup_property_cache(db)
            logger.info(
                f"🎉 Startup cache warmup completed: {stats['success']}/{stats['total']} properties cached"
            )
        except Exception as e:
            logger.error(f"❌ Startup cache warmup failed: {e}")
            # 不抛出异常,避免阻止应用启动
